package logic

import (
	"context"
	"strings"

	"mall/common/enumx"
	"mall/common/modelx"
	"mall/common/resultx"
	"mall/service/blog/model"
	"mall/service/blog/rpc/internal/svc"
	"mall/service/blog/rpc/types/blog"

	"github.com/zeromicro/go-zero/core/logx"
)

type SearchInitLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewSearchInitLogic(ctx context.Context, svcCtx *svc.ServiceContext) *SearchInitLogic {
	return &SearchInitLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *SearchInitLogic) SearchInit(in *blog.SearchInitReq) (*blog.SearchInitResp, error) {
	// logx.Infof("SearchInitReq: %+v ", in)
	// Limit:5 Preload:\"blogBook:Id,Title,Slug;blogMedia:Uid,Id,Url,Thumbnail,Order;blogBookRelation:brand\" EagerLoad:\"blogBook:blogMedia,blogBookRelation\" Filter:\"perfume,brand,group,note,nose\" PreFilter:\"brand,group,note,nose\" VisitorId:10002 PlatformId:1

	if in.Preload == "" || in.EagerLoad == "" || in.PlatformId == 0 {
		return nil, resultx.StatusError(resultx.REUQEST_PARAM_ERROR, "")
	}

	preloadMap, eagerLoadMap := modelx.GetPreloadMap(in.Preload, in.EagerLoad)
	// logx.Infof("preloadMap: %+v ", preloadMap)
	// map[blogBook:[Id Title Slug] blogBookRelation:[brand] blogMedia:[Uid Id Url Thumbnail Order]]
	// logx.Infof("eagerLoadMap: %+v ", eagerLoadMap)
	// map[blogBook:[blogMedia blogBookRelation]]

	blogBookEntityName := model.RpcEntityNames.BlogBook
	_, hasSettingMap := model.RpcEntityPreloadMap[blogBookEntityName] // BlogKnowledgeBasis的关联字段
	if !hasSettingMap {
		return &blog.SearchInitResp{}, nil
	}

	blogBookRepositoryName := model.RepositoryNames.BlogBook
	columnMap, hasColumnMap := model.RepositoryPreloadMap[blogBookRepositoryName] // BlogKnowledgeBasis的数据库字段
	if !hasColumnMap {
		return &blog.SearchInitResp{}, nil
	}

	blogBookRelationEntityName := model.RpcEntityNames.BlogBookRelation
	blogBookRelationSettingMap, hasBlogBookRelationSettingMap := model.RpcEntityPreloadMap[blogBookRelationEntityName]
	if !hasBlogBookRelationSettingMap {
		return &blog.SearchInitResp{}, nil
	}

	var selectCols []string
	if preloadFields, hasPreloadFields := preloadMap[blogBookEntityName]; hasPreloadFields {
		selectColMap := make(map[string]string)
		for _, field := range preloadFields {
			if _, exist := selectColMap[field]; !exist {
				if column, hasColumn := columnMap[field]; hasColumn {
					selectColMap[field] = column
				} else {
					selectColMap[field] = ""
				}
			}
		}
		for _, column := range selectColMap {
			if column != "" {
				selectCols = append(selectCols, column)
			}
		}
	}
	selectColumns := strings.Join(selectCols, ",")

	subEntitySettingMap := make(map[string]map[string]*model.ColumnSetting)
	if eagerLoadEntities, hasEagerLoadEntities := eagerLoadMap[blogBookEntityName]; hasEagerLoadEntities {
		for _, entity := range eagerLoadEntities {
			if entitySettingMap, hasEntitySettingMap := model.RpcEntityPreloadMap[entity]; hasEntitySettingMap {
				subEntitySettingMap[entity] = entitySettingMap
			}
		}
	}

	var logList []*blog.BookDetailResp
	var userLogList []*blog.BookDetailResp
	var groupFilterList []*blog.BookDetailResp
	var noteFilterList []*blog.BookDetailResp
	var brandFilterList []*blog.BookDetailResp
	var noseFilterList []*blog.BookDetailResp
	idSectionMap := make(map[uint64][]*blog.BlogCategory) // Map: model.BlogKnowledgeBasis.ID => []*blog.BlogCategory
	if in.Filter != "" { // 搜索记录的筛选
		var sectionIds []interface{}
		sectionMap := make(map[uint64]string) // BlogBookRelation 的 id、 别名 map
		for _, s := range blogBookRelationSettingMap {
			if s.Id > 0 {
				if _, exist := sectionMap[s.Id]; !exist {
					sectionMap[s.Id] = s.Name
					if strings.Contains("," + in.Filter + ",", "," + s.Name + ",") {
						sectionIds = append(sectionIds, s.Id)
					}
				}
			}
		}

		preFilterMap := make(map[string]map[string][]interface{})
		preFilterMap[model.BlogUserClickLogColumns.PlatformID] = map[string][]interface{}{
			"equalTo": []interface{}{in.PlatformId},
		}
		preFilterMap[model.BlogUserClickLogColumns.SectionID] = map[string][]interface{}{
			"in": sectionIds,
		}
		preFilterMap[model.BlogUserClickLogColumns.ObjectType] = map[string][]interface{}{
			"equalTo": []interface{}{enumx.PostTypeKnowledgeBase},
		}
		preFilterMap[model.BlogUserClickLogColumns.SearchLogID] = map[string][]interface{}{
			"moreThan": []interface{}{0},
		}
		orderBy := modelx.GetOrderBy(in.Sorter, columnMap)
		if orderBy == "" {
			orderBy = model.BlogUserClickLogColumns.ClickLogID + " DESC"
		}
		if in.VisitorId > 0 { // 我的搜索记录
			preFilterMap[model.BlogUserClickLogColumns.UserID] = map[string][]interface{}{
				"equalTo": []interface{}{in.VisitorId},
			}
			objList, _, err := l.svcCtx.BlogUser.GetClickObjectList(l.ctx, model.M{
				"pageSize": int64(in.Limit),
				"orderBy":  orderBy,
				"select":   model.BlogUserClickLogColumns.ObjectID + "," + model.BlogUserClickLogColumns.SectionID,
			}, -1, preFilterMap)
			if err != nil {
				return nil, err
			}

			if len(objList) > 0 {
				var oids []interface{} // []model.BlogUserClickLog.ObjectID
				for _, obj := range objList {
					oids = append(oids, obj.ObjectID)
					if section, exist := sectionMap[obj.SectionID]; exist {
						if _, ok := idSectionMap[obj.ObjectID]; !ok {
							idSectionMap[obj.ObjectID] = append(idSectionMap[obj.ObjectID], &blog.BlogCategory{
								Id:  int64(obj.SectionID),
								Uri: section,
							})
						}
					}
				}
				logEntryList, err := l.getEntryList(oids, selectColumns)
				if err != nil {
					return nil, err
				}

				if len(logEntryList) > 0 {
					logList, err = l.parseEntryList(logEntryList, preloadMap, subEntitySettingMap, idSectionMap)
					if err != nil {
						return nil, err
					}
				}
			}

			preFilterMap[model.BlogUserClickLogColumns.UserID] = map[string][]interface{}{
				"notEqualTo": []interface{}{in.VisitorId},
			}
			objList, _, err = l.svcCtx.BlogUser.GetClickObjectList(l.ctx, model.M{
				"pageSize": int64(in.Limit * 2),
				"orderBy":  orderBy,
				"select":   model.BlogUserClickLogColumns.ObjectID + "," + model.BlogUserClickLogColumns.SectionID,
			}, -1, preFilterMap)
			if err != nil {
				return nil, err
			}

			if len(objList) > 0 {
				var oids []interface{} // []model.BlogUserClickLog.ObjectID
				for _, obj := range objList {
					oids = append(oids, obj.ObjectID)
					if section, exist := sectionMap[obj.SectionID]; exist {
						if _, ok := idSectionMap[obj.ObjectID]; !ok {
							idSectionMap[obj.ObjectID] = append(idSectionMap[obj.ObjectID], &blog.BlogCategory{
								Id:  int64(obj.SectionID),
								Uri: section,
							})
						}
					}
				}
				userLogEntryList, err := l.getEntryList(oids, selectColumns)
				if err != nil {
					return nil, err
				}

				if len(userLogEntryList) > 0 {
					userLogList, err = l.parseEntryList(userLogEntryList, preloadMap, nil, idSectionMap)
					if err != nil {
						return nil, err
					}
				}
			}
		} else {
			objList, _, err := l.svcCtx.BlogUser.GetClickObjectList(l.ctx, model.M{
				"pageSize": int64(in.Limit * 2),
				"orderBy":  orderBy,
				"select":   model.BlogUserClickLogColumns.ObjectID + "," + model.BlogUserClickLogColumns.SectionID,
			}, -1, preFilterMap)
			if err != nil {
				return nil, err
			}

			if len(objList) > 0 {
				var oids []interface{} // []model.BlogUserClickLog.ObjectID
				for _, obj := range objList {
					oids = append(oids, obj.ObjectID)
					if section, exist := sectionMap[obj.SectionID]; exist {
						if _, ok := idSectionMap[obj.ObjectID]; !ok {
							idSectionMap[obj.ObjectID] = append(idSectionMap[obj.ObjectID], &blog.BlogCategory{
								Id:  int64(obj.SectionID),
								Uri: section,
							})
						}
					}
				}
				userLogEntryList, err := l.getEntryList(oids, selectColumns)
				if err != nil {
					return nil, err
				}

				if len(userLogEntryList) > 0 {
					userLogList, err = l.parseEntryList(userLogEntryList, preloadMap, nil, idSectionMap)
					if err != nil {
						return nil, err
					}
				}
			}
		}
	}

	if in.PreFilter != "" { // 筛选项的配置
		sectionMap := make(map[string]uint64) // BlogBookRelation 的 id、 别名 map
		for _, s := range blogBookRelationSettingMap {
			if s.Name != "" && s.Id > 0 {
				sectionMap[s.Name] = s.Id
			}
		}

		filters := strings.Split(in.PreFilter, ",")
		for _, filter := range filters {
			if sectionId, exist := sectionMap[filter]; exist {
				var err error
				switch filter {
				case "brand":
					brandEntryList, err := l.getRecommendEntryList(sectionId, in.Limit, selectColumns)
					if err != nil {
						return nil, err
					}

					if len(brandEntryList) > 0 {
						brandFilterList, err = l.parseEntryList(brandEntryList, preloadMap, subEntitySettingMap, nil)
					}
				case "nose":
					noseEntryList, err := l.getRecommendEntryList(sectionId, in.Limit, selectColumns)
					if err != nil {
						return nil, err
					}

					if len(noseEntryList) > 0 {
						noseFilterList, err = l.parseEntryList(noseEntryList, preloadMap, subEntitySettingMap, nil)
					}
				case "group":
					groupEntryList, err := l.getRecommendEntryList(sectionId, in.Limit, selectColumns)
					if err != nil {
						return nil, err
					}

					if len(groupEntryList) > 0 {
						groupFilterList, err = l.parseEntryList(groupEntryList, preloadMap, subEntitySettingMap, nil)
					}
				case "note":
					noteEntryList, err := l.getRecommendEntryList(sectionId, in.Limit, selectColumns)
					if err != nil {
						return nil, err
					}

					if len(noteEntryList) > 0 {
						noteFilterList, err = l.parseEntryList(noteEntryList, preloadMap, subEntitySettingMap, nil)
					}
				}
				if err != nil {
					return nil, err
				}
			}
		}
	}

	return &blog.SearchInitResp{
		LogList: logList,
		UserLogList: userLogList,
		GroupFilterList: groupFilterList,
		NoteFilterList: noteFilterList,
		BrandFilterList: brandFilterList,
		NoseFilterList: noseFilterList,
	}, nil
}

func (l *SearchInitLogic) getRecommendEntryList(
	sectionId uint64,
	limit int32,
	selectStr string,
) (entryList []*model.BlogKnowledgeBasis, err error) {
	filterMap := make(map[string]map[string][]interface{})
	filterMap[model.BlogTermRelationshipColumns.TermID] = map[string][]interface{}{
		"equalTo": []interface{}{sectionId},
	}
	filterMap[model.BlogTermRelationshipColumns.ObjectType] = map[string][]interface{}{
		"equalTo": []interface{}{enumx.PostTypeKnowledgeBase},
	}
	relationshipList, _, preErr := l.svcCtx.BlogTerm.GetRelationshipList(l.ctx, model.M{
		"pageSize": int64(limit),
		"random":   "1",
		"select":   model.BlogTermRelationshipColumns.ObjectID,
	}, -1, filterMap)
	if preErr != nil {
		err = preErr
		return
	}

	var oids []interface{} // []model.BlogTermRelationship.ObjectID(已去重)
	if len(relationshipList) > 0 {
		oidMap := make(map[uint64]int) // Map: model.BlogTermRelationship.ObjectID => int
		for i, relationship := range relationshipList {
			if relationship.ObjectID == 0 {
				continue
			}

			if _, exist := oidMap[relationship.ObjectID]; !exist {
				oids = append(oids, relationship.ObjectID)
				oidMap[relationship.ObjectID] = i
			}
		}
	}
	if len(oids) > 0 {
		subFilterMap := make(map[string]map[string][]interface{})
		subFilterMap[model.BlogKnowledgeBasisColumns.ID] = map[string][]interface{}{
			"in": oids,
		}
		subFilterMap[model.BlogKnowledgeBasisColumns.PostStatus] = map[string][]interface{}{
			"equalTo": []interface{}{enumx.PostStatusPublish},
		}
		entryList, _, err = l.svcCtx.BlogBook.GetList(l.ctx, model.M{
			"select": selectStr,
		}, -1, subFilterMap)
	}

	return
}

func (l *SearchInitLogic) getEntryList(oids []interface{}, selectCols string) (entryList []*model.BlogKnowledgeBasis, err error) {
	if len(oids) > 0 {
		filterMap := make(map[string]map[string][]interface{})
		filterMap[model.BlogKnowledgeBasisColumns.ID] = map[string][]interface{}{
			"in": oids,
		}
		filterMap[model.BlogKnowledgeBasisColumns.PostStatus] = map[string][]interface{}{
			"equalTo": []interface{}{enumx.PostStatusPublish},
		}
		tmpList, _, tmpErr := l.svcCtx.BlogBook.GetList(l.ctx, model.M{
			"select": selectCols,
		}, -1, filterMap)
		if tmpErr != nil {
			return nil, tmpErr
		}

		tmpMap := make(map[interface{}]*model.BlogKnowledgeBasis)
		for _, tmp := range tmpList {
			tmpMap[tmp.ID] = tmp
		}
		for _, oid := range oids {
			if tmp, exist := tmpMap[oid]; exist {
				entryList = append(entryList, tmp)
			}
		}
	}

	return
}

func (l *SearchInitLogic) parseEntryList(
	entryList []*model.BlogKnowledgeBasis,
	preloadMap map[string][]string,
	subEntitySettingMap map[string]map[string]*model.ColumnSetting,
	idSectionMap map[uint64][]*blog.BlogCategory,
) (entries []*blog.BookDetailResp, err error) {
	var ids []interface{} // []model.BlogKnowledgeBaseDetail.ID
	for _, entry := range entryList {
		ids = append(ids, entry.ID)
	}

	idMediaMap := make(map[uint64]*blog.BlogMedia) // Map: model.BlogKnowledgeBasis.ID => *blog.BlogMedia
	if subEntitySettingMap != nil {
		blogMediaEntityName := model.RpcEntityNames.BlogMedia
		blogMediaRepositoryName := model.RepositoryNames.BlogMedia
		if _, hasEntitySettingMap := subEntitySettingMap[blogMediaEntityName]; hasEntitySettingMap {
			preloadFields, hasPreloadFields := preloadMap[blogMediaEntityName]
			columnMap, hasColumnMap := model.RepositoryPreloadMap[blogMediaRepositoryName]
			if hasPreloadFields && hasColumnMap {
				selectColMap := make(map[string]string)
				for _, field := range preloadFields {
					if _, exist := selectColMap[field]; !exist {
						if column, hasColumn := columnMap[field]; hasColumn {
							selectColMap[field] = column
						} else {
							selectColMap[field] = ""
						}
					}
				}
				var selectCols []string
				for _, column := range selectColMap {
					if column != "" {
						selectCols = append(selectCols, column)
					}
				}
				mediaFilterMap := make(map[string]map[string][]interface{})
				mediaFilterMap[model.BlogAttachmentRelationshipColumns.ObjectID] = map[string][]interface{}{
					"in": ids,
				}
				mediaFilterMap[model.BlogAttachmentRelationshipColumns.ObjectType] = map[string][]interface{}{
					"equalTo": []interface{}{enumx.PostTypeKnowledgeBase},
				}
				mediaFilterMap[model.BlogAttachmentRelationshipColumns.AttachmentThumbnail] = map[string][]interface{}{
					"equalTo": []interface{}{1},
				}
				mediaList, _, err := l.svcCtx.BlogBook.GetMedia(l.ctx, model.M{
					"orderBy": model.BlogAttachmentRelationshipColumns.AttachmentOrder,
					"select": strings.Join(selectCols, ","),
				}, -1, mediaFilterMap) // 读取关联表
				if err != nil {
					return nil, err
				}

				if len(mediaList) > 0 {
					for _, media := range mediaList {
						if _, exist := idMediaMap[media.ObjectID]; !exist {
							idMediaMap[media.ObjectID] = &blog.BlogMedia{
								Uid:       int64(media.AttachmentRelationshipID),
								Id:        int64(media.AttachmentID),
								Uri:       media.AttachmentSource,
								Thumbnail: int32(media.AttachmentThumbnail),
								Order:     int32(media.AttachmentOrder),
								Url:       media.AttachmentImageURL,
								AltText:   media.AttachmentImageAlt,
								Meta:      media.AttachmentImageMeta,
							}
						}
					}
				}
			}
		}
	}
	

	idMetaMap := make(map[uint64]*blog.BlogMeta) // Map: model.BlogKnowledgeBasis.ID => *blog.BlogMeta
	if subEntitySettingMap != nil {
		blogBookMetaEntityName := model.RpcEntityNames.BlogBookMeta
		if entitySettingMap, hasEntitySettingMap := subEntitySettingMap[blogBookMetaEntityName]; hasEntitySettingMap {
			if preloadFields, hasPreloadFields := preloadMap[blogBookMetaEntityName]; hasPreloadFields {
				var metaKeys []interface{}
				for _, field := range preloadFields {
					fieldSetting, hasFieldSetting := entitySettingMap[field]
					if hasFieldSetting && fieldSetting.Name != "" {
						metaKeys = append(metaKeys, fieldSetting.Name)
					}
				}
				if len(metaKeys) > 0 {
					metaFilterMap := make(map[string]map[string][]interface{})
					metaFilterMap[model.BlogKnowledgeBaseMetumColumns.KnowledgeBaseID] = map[string][]interface{}{
						"in": ids,
					}
					metaFilterMap[model.BlogKnowledgeBaseMetumColumns.MetaKey] = map[string][]interface{}{
						"in": metaKeys,
					}
					metaList, _, err := l.svcCtx.BlogBook.GetMeta(l.ctx, model.M{}, -1, metaFilterMap)
					if err != nil {
						return nil, err
					}

					if len(metaList) > 0 {
						for _, metum := range metaList {
							if metum.MetaKey != "" && metum.MetaValue.Valid {
								if _, exist := idMetaMap[metum.KnowledgeBaseID]; !exist {
									idMetaMap[metum.KnowledgeBaseID] = &blog.BlogMeta{
										Id: int64(metum.MetaID),
										Key: metum.MetaKey,
										Value: metum.MetaValue.String,
									}
								}
							}
						}
					}
				}
			}
		}
	}

	idEntriesMap := make(map[uint64][]*blog.BlogEntry) // Map: model.BlogKnowledgeBasis.ID => []*blog.BlogEntry
	if subEntitySettingMap != nil {
		blogBookRelationEntityName := model.RpcEntityNames.BlogBookRelation
		blogBookRelationRepositoryName := model.RepositoryNames.BlogBookRelation
		if entitySettingMap, hasEntitySettingMap := subEntitySettingMap[blogBookRelationEntityName]; hasEntitySettingMap {
			preloadFields, hasPreloadFields := preloadMap[blogBookRelationEntityName]
			columnMap, hasColumnMap := model.RepositoryPreloadMap[blogBookRelationRepositoryName]
			if hasPreloadFields && hasColumnMap {
				preloadMap := make(map[string]int)
				selectColMap := make(map[string]string)
				for idx, field := range preloadFields {
					if _, exist := preloadMap[field]; !exist { // 确定relation的key及entry的字段
						preloadMap[field] = idx
						if column, hasColumn := columnMap[field]; hasColumn {
							selectColMap[field] = column
						} else {
							selectColMap[field] = ""
						}
					}
				}

				var sectionIds []interface{}
				sectionMap := make(map[uint64]string)  // BlogBookRelation 的 id、 别名 map
				for _, s := range entitySettingMap {
					if s.Id > 0 {
						if _, exist := preloadMap[s.Name]; exist {
							sectionIds = append(sectionIds, s.Id)
						}
						sectionMap[s.Id] = s.Name
					}
				}
				if len(sectionIds) > 0 { // relation 的 section id 数组不为空
					var selectCols []string
					for _, column := range selectColMap {
						if column != "" {
							selectCols = append(selectCols, column)
						}
					}

					var relationList []*model.BlogKnowledgeBaseRelationship
					relationFilterMap := make(map[string]map[string][]interface{})
					relationFilterMap[model.BlogKnowledgeBaseRelationshipColumns.FromEntryID] = map[string][]interface{}{
						"in": ids,
					}
					relationFilterMap[model.BlogKnowledgeBaseRelationshipColumns.ToSectionID] = map[string][]interface{}{
						"in": sectionIds,
					}
					relationSelectCols := []string{
						model.BlogKnowledgeBaseRelationshipColumns.FromEntryID,
						model.BlogKnowledgeBaseRelationshipColumns.ToEntryID,
						model.BlogKnowledgeBaseRelationshipColumns.ToSectionID,
						model.BlogKnowledgeBaseRelationshipColumns.ToEntryGroup,
						model.BlogKnowledgeBaseRelationshipColumns.ToEntryOrder,
						model.BlogKnowledgeBaseRelationshipColumns.ToEntryMeta,
					}
					relationList, _, err = l.svcCtx.BlogBook.GetRelationshipList(l.ctx, model.M{
						"select":  strings.Join(relationSelectCols, ","),
						"orderBy": model.BlogKnowledgeBaseRelationshipColumns.ToEntryOrder,
					}, -1, relationFilterMap)
					if err != nil {
						return nil, err
					}

					if len(relationList) > 0 {
						idRelationsMap := make(map[uint64][]*model.BlogKnowledgeBaseRelationship)
						tidMap := make(map[uint64]int) // tids 去重 Map: model.BlogKnowledgeBasis.ID => int
						var tids []interface{}
						for idx, relation := range relationList {
							if _, exist := tidMap[relation.ToEntryID]; !exist {
								tidMap[relation.ToEntryID] = idx
								tids = append(tids, relation.ToEntryID)
							}
							idRelationsMap[relation.FromEntryID] = append(idRelationsMap[relation.FromEntryID], relation)
						}
						
						if len(tids) > 0 {
							entryFilterMap := make(map[string]map[string][]interface{})
							entryFilterMap[model.BlogKnowledgeBasisColumns.ID] = map[string][]interface{}{
								"in": tids,
							}
							entryFilterMap[model.BlogKnowledgeBasisColumns.PostStatus] = map[string][]interface{}{
								"equalTo": []interface{}{enumx.PostStatusPublish},
							}
							var entrySelectCols []string
							if len(selectCols) > 0 {
								entrySelectCols = selectCols[:]
							} else {
								entrySelectCols = []string{
									model.BlogKnowledgeBasisColumns.ID,
									model.BlogKnowledgeBasisColumns.PostTitle,
									model.BlogKnowledgeBasisColumns.PostName,
									model.BlogKnowledgeBasisColumns.GUID,
								}
							}
							relationEntryList, _, listErr := l.svcCtx.BlogBook.GetList(l.ctx, model.M{
								"select": strings.Join(entrySelectCols, ","),
							}, -1, entryFilterMap)
							if listErr != nil {
								return nil, listErr
							}

							relationEntryMap := make(map[uint64]*model.BlogKnowledgeBasis)
							for _, e := range relationEntryList {
								relationEntryMap[e.ID] = e
							}
							for id, rs := range idRelationsMap {
								entryMap := make(map[uint64]int) // Map: model.BlogKnowledgeBasis.ID => int
								for i, r := range rs {
									if _, exist := entryMap[r.ToEntryID]; exist {
										continue
									}

									entryMap[r.ToEntryID] = i
									if e, exist := relationEntryMap[r.ToEntryID]; exist {
										var section string
										if s, ok := sectionMap[r.ToSectionID]; ok {
											section = s
										}
										idEntriesMap[id] = append(idEntriesMap[id], &blog.BlogEntry{
											Id:        int64(e.ID),
											Title:     e.PostTitle,
											Slug:      e.PostName,
											Link:      e.GUID,
											SectionId: int64(r.ToSectionID),
											Section:   section,
											GroupId:   int64(r.ToEntryGroup),
											Order:     int64(r.ToEntryOrder),
										})
									}
								}
							}
						}
					}
				}
			}
		}
	}

	for _, entry := range entryList {
		var sections []*blog.BlogCategory
		if idSectionMap != nil {
			if terms, exist := idSectionMap[entry.ID]; exist {
				sections = terms[:]
			}
		}
		var media []*blog.BlogMedia
		if m, exist := idMediaMap[entry.ID]; exist {
			media = append(media, m)
		}
		var es []*blog.BlogEntry
		if res, exist := idEntriesMap[entry.ID]; exist {
			es = res[:]
		}
		entries = append(entries, &blog.BookDetailResp{
			Id:            int64(entry.ID),
			ParentId:      int64(entry.PostParentID),
			Title:         entry.PostTitle,
			Excerpt:       entry.PostExcerpt,
			Status:        int32(entry.PostStatus),
			CommentStatus: int32(entry.CommentStatus),
			Slug:          entry.PostName,
			Uri:           entry.GUID,
			Date:          modelx.FormatTime(entry.PostDate, ""),
			DateGmt:       modelx.FormatTime(entry.PostDateGMT, ""),
			Modified:      modelx.FormatTime(entry.PostModifiedDate, ""),
			ModifiedGmt:   modelx.FormatTime(entry.PostModifiedGMT, ""),
			Order:         int64(entry.MenuOrder),
			CommentCount:  int32(entry.CommentCount),
			Media:         media,
			Sections:      sections,
			Relations:     es,
		})
	}

	return
}
